package org.zjt.design.pattern;

import java.util.Objects;
import static java.lang.System.out;

/**
 * @author <a href="juntao.zhang@qq.com">juntao.zhang</a>
 * @Description: 单例模式
 * @Package org.zjt.design.pattern
 * @date 2018/5/8 14:02
 * @see
 */
public class SingletonTest {

    public static void main(String[] args) {

        out.printf("----------------%s-----------------\n","使用内部类实现单例模式");
        new Thread(()->out.println(Singleton1.getInstance())).start();
        new Thread(()->out.println(Singleton1.getInstance())).start();


        out.printf("----------------%s-----------------\n","饿汉  初始化加载");
        new Thread(()->out.println(Singleton2.getInstance())).start();
        new Thread(()->out.println(Singleton2.getInstance())).start();


        out.printf("----------------%s-----------------\n","饱汉 延迟加载");
        new Thread(()->out.println(Singleton3.getInstance())).start();
        new Thread(()->out.println(Singleton3.getInstance())).start();

        out.printf("----------------%s-----------------\n","双重检验  延迟加载");
        new Thread(()->out.println(Singleton4.getInstance())).start();
        new Thread(()->out.println(Singleton4.getInstance())).start();


        out.printf("----------------%s-----------------\n","枚举  及时加载");
        new Thread(()->out.println(Singleton5.getInstance())).start();
        new Thread(()->out.println(Singleton5.getInstance())).start();
    }
}


/**
 * 使用内部类实现单例模式
 */
class Singleton1{

    private Singleton1(){

    }

    /**
     * 内部类实现单例模式
     */
    static class SingletonHolder{
        private static Singleton1 singleton = new Singleton1();
    }

    public static Singleton1 getInstance(){
        return SingletonHolder.singleton;
    }

}


/**
 * 饿汉  初始化加载
 */
class Singleton2{

    private static Singleton2 singleton = new Singleton2();
    private Singleton2(){

    }
    public static Singleton2 getInstance(){
        return singleton;
    }
}

/**
 * 饱汉 延迟加载
 *
 */
class Singleton3{

    private static Singleton3 singleton ;
    private Singleton3(){

    }
    public static synchronized Singleton3 getInstance(){
        if (Objects.isNull(singleton))
            singleton = new Singleton3();
        return singleton;
    }
}

/**
 * 双重检验单例
 */
class Singleton4{

    private static Singleton4 singleton ;
    private Singleton4(){

    }

    public static Singleton4 getInstance(){
        if (Objects.isNull(singleton)){
            synchronized (Singleton4.class){
                if (Objects.isNull(singleton))
                    singleton = new Singleton4();
            }
        }
        return singleton;
    }
}

/**
 * 枚举实现单例模式
 */
enum Singleton5{
    INSTANCE;

    public static Singleton5 getInstance(){
        return INSTANCE;
    }
}